package it.unicam.cs.cosy.bioshape.gui.visualizer3d;

import java.util.ArrayList;
import java.util.Enumeration;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Geometry;
import javax.media.j3d.Group;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;

/**
 * Wraps a {@code TransformGroup} object providing abilities to glue together
 * shapes. In particular an object has always a defined list of edges on which
 * it is defined. These edges define also the list of rules.
 * 
 * @author Federico Buti
 */
public class TransShape extends BranchGroup {
	String name;
	ArrayList<TransShape> shapes;
	TransformGroup tg;
	Transform3D tr;
	BranchGroup bg;

	// Luca: Non serve
//	TransShape(String name, Enumeration<Geometry> geoms) {
//		this.name = name;
//		Shape3D shape = new Shape3D();
//		for (Enumeration<Geometry> e = geoms; e.hasMoreElements();)
//			shape.addGeometry(e.nextElement());
//		tg = new TransformGroup();
//		tg.addChild(shape);
//		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
//		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//		tr = new Transform3D();
//	}

	TransShape(String name, Geometry[] geometries) {
		this.name = name;
		Shape3D shape = new Shape3D();
		for (Geometry g : geometries)
			shape.addGeometry(g);
		tg = new TransformGroup();
		tg.addChild(shape);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		tr = new Transform3D();
	}

	// Luca: non serve
//	TransShape(String name, Enumeration<Geometry> geoms, Appearance app) {
//		this.name = name;
//		Shape3D shape = new Shape3D();
//		shape.setAppearance(app);
//		for (Enumeration<Geometry> e = geoms; e.hasMoreElements();)
//			shape.addGeometry(e.nextElement());
//		tg = new TransformGroup();
//		tg.addChild(shape);
//	}

	/**
	 * // TODO Luca: servirà per il bind? 
	 * @param shape1
	 * @param shape2
	 * @param t1
	 * @param t2
	 * @param t3
	 */
	TransShape(TransShape shape1, TransShape shape2, double[] t1, double[] t2,
			double[] t3) {
		this.name = shape1.name + "-" + shape2.name;
		shapes = new ArrayList<TransShape>();
		shapes.add(shape1);
		shapes.add(shape2);
		tg = new TransformGroup();
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		shape1.updatePosition(t1);
		shape2.updatePosition(t2);
		tg.addChild(shape1.tg);
		tg.addChild(shape2.tg);
		updatePosition(t3);
	}

	// /**
	// *
	// * @param shape1
	// * @param shape2
	// * @param t1
	// * @param t2
	// * @param t3
	// */
	// TransShape removeShape(String master, String removable) {
	// return null;
	// }

	// /**
	// *
	// * @param shape1
	// * @param shape2
	// * @param t1
	// * @param t2
	// * @param t3
	// */
	// TransShape removeShape(String master, String[] removable) {
	// return null;
	// }

	void updatePosition(double[] t) {
		tr.set(t);
		tg.setTransform(tr);
	}

	void updatePosition(Transform3D t) {
		tg.setTransform(t);
	}

	BranchGroup getHandle() {
		bg = new BranchGroup();
		bg.setCapability(BranchGroup.ALLOW_DETACH);
		bg.setCapability(Group.ALLOW_CHILDREN_READ);
		bg.setCapability(Group.ALLOW_CHILDREN_WRITE);
		bg.setCapability(Group.ALLOW_CHILDREN_EXTEND);
		bg.addChild(tg);
		return bg;
	}
}